package com.dex4d.core;

import android.app.Activity;
import android.app.Application;
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.migration.Migration;
import android.content.Context;
import android.os.Environment;
import android.support.multidex.MultiDex;

import com.dex4d.BuildConfig;
import com.dex4d.R;
import com.dex4d.db.AppDatabase;
import com.dex4d.ui.demo.HomeActivity;
import com.dex4d.ui.main.activity.AccountActivity;
import com.dex4d.ui.main.activity.TradeActivity;
import com.dex4d.ui.main.socket.Client;
import com.dex4d.ui.main.socket.RPC;
import com.dex4d.utils.AppStatusTracker;
import com.dex4d.utils.LogUtils;
import com.dex4d.utils.SPUtil;
import com.google.gson.Gson;
import com.koushikdutta.async.http.WebSocket;
import com.squareup.leakcanary.RefWatcher;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;

import org.greenrobot.eventbus.EventBus;

public class CustomApplication extends Application implements WebSocket.StringCallback, AppLifeCycleCallback.BecameListener {
    private static CustomApplication mInstance;
    private static Context mContext;
    private RefWatcher mRefWatcher;
    private static AppDatabase db;

    private static Client client;
    private static AppLifeCycleCallback lifeCycleCallback;//Activity的生命周期监测


    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        mContext = getApplicationContext();
        AppStatusTracker.init(this);
        //mRefWatcher = BuildConfig.DEBUG ?  LeakCanary.install(this) : RefWatcher.DISABLED;

        //初始化sp文件
        SPUtil.setContext(mContext);

        //初始化Log工具类
        initLogUtils();

        //初始化数据库
        initDatabase();

        initWebSocket();

        upgrade();

    }

    /**
     * 版本升级设置
     */
    public void upgrade() {

        /**
         * true表示app启动自动初始化升级模块; false不会自动初始化;
         * 开发者如果担心sdk初始化影响app启动速度，可以设置为false，
         * 在后面某个时刻手动调用Beta.init(getApplicationContext(),false);
         */
        Beta.autoInit = true;

        /**
         * true表示初始化时自动检查升级; false表示不会自动检查升级,需要手动调用Beta.checkUpgrade()方法;
         */
        Beta.autoCheckUpgrade = true;

        /**
         * 设置升级检查周期为60s(默认检查周期为0s)，60s内SDK不重复向后台请求策略);
         */
        Beta.upgradeCheckPeriod = 60 * 1000;

        /**
         * 设置启动延时为1s（默认延时3s），APP启动1s后初始化SDK，避免影响APP启动速度;
         */
        Beta.initDelay = 5 * 1000;

        /**
         * 设置通知栏大图标，largeIconId为项目中的图片资源;
         */
        Beta.largeIconId = R.mipmap.ic_launcher;

        /**
         * 设置状态栏小图标，smallIconId为项目中的图片资源Id;
         */
        Beta.smallIconId = R.mipmap.ic_launcher;

        /**
         * 设置更新弹窗默认展示的banner，defaultBannerId为项目中的图片资源Id;
         * 当后台配置的banner拉取失败时显示此banner，默认不设置则展示“loading“;
         */
        Beta.defaultBannerId = R.mipmap.ic_launcher;

        /**
         * 设置sd卡的Download为更新资源保存目录;
         * 后续更新资源会保存在此目录，需要在manifest中添加WRITE_EXTERNAL_STORAGE权限;
         */
        Beta.storageDir = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        /**
         * 已经确认过的弹窗在APP下次启动自动检查更新时会再次显示;
         */
        Beta.showInterruptedStrategy = true;

        /**
         * 只允许在HomeActivity上显示更新弹窗，其他activity上不显示弹窗; 不设置会默认所有activity都可以显示弹窗;
         */
        Beta.canShowUpgradeActs.add(HomeActivity.class);

        /**
         * 设置Wifi下自动下载
         */
        Beta.autoDownloadOnWifi = true;


        /**
         * 设置是否显示消息通知
         */
        Beta.enableNotification = true;

        /**
         * 设置是否显示弹窗中的apk信息
         */
        Beta.canShowApkInfo = true;


        /**
         * 设置app渠道号
         */
//        BuglyStrategy strategy = new BuglyStrategy();
//        strategy.setAppChannel("Dex4D");

        /**
         * 设置自定义升级对话框UI布局
         */
        Beta.upgradeDialogLayoutId = R.layout.upgrade_dialog;


        /**
         * 设置自定义tip弹窗UI布局
         */
        Beta.tipsDialogLayoutId = R.layout.tips_dialog;


//        Bugly.init(getApplicationContext(), "41785655a4", BuildConfig.DEBUG, strategy);
        Bugly.init(getApplicationContext(), "41785655a4", BuildConfig.DEBUG);
    }

    /**
     *
     */
    private void initWebSocket() {

        lifeCycleCallback = new AppLifeCycleCallback(this, this);
        registerActivityLifecycleCallbacks(lifeCycleCallback);

        client = new Client("ws://106.75.25.3", 8604);
        client.setStringCallback(this);
    }

    public static Client getClient() {
        return client;
    }

    public static Context getContextObject() {
        return mContext;
    }

    public static CustomApplication getInstance() {
        return mInstance;
    }

    public static RefWatcher getRefWatcher() {
        return getInstance().mRefWatcher;
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    //如果是HTTP请求，调用
//    private void initSSl(){
//        try {
//            ProviderInstaller.installIfNeeded(getApplicationContext());
//            SSLContext sslContext;
//            sslContext = SSLContext.getInstance("TLSv1.2");
//            sslContext.init(null, null, null);
//            sslContext.createSSLEngine();
//        } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
//                | NoSuchAlgorithmException | KeyManagementException e) {
//            e.printStackTrace();
//        }
//    }

    private void initLogUtils() {
        final LogUtils.Config config = LogUtils.getConfig()
                .setLogSwitch(BuildConfig.DEBUG)// 设置 log 总开关，包括输出到控制台和文件，默认开
                .setConsoleSwitch(BuildConfig.DEBUG)// 设置是否输出到控制台开关，默认开
                .setGlobalTag(null)// 设置 log 全局标签，默认为空
                // 当全局标签不为空时，我们输出的 log 全部为该 tag，
                // 为空时，如果传入的 tag 为空那就显示类名，否则显示 tag
                .setLogHeadSwitch(true)// 设置 log 头信息开关，默认为开
                .setLog2FileSwitch(true)// 打印 log 时是否存到文件的开关，默认关
                .setDir("")// 当自定义路径为空时，写入应用的/cache/log/目录中
                .setFilePrefix("")// 当文件前缀为空时，默认为"util"，即写入文件为"util-MM-dd.txt"
                .setBorderSwitch(true)// 输出日志是否带边框开关，默认开
                .setSingleTagSwitch(true)// 一条日志仅输出一条，默认开，为美化 AS 3.1 的 Logcat
                .setConsoleFilter(LogUtils.V)// log 的控制台过滤器，和 logcat 过滤器同理，默认 Verbose
                .setFileFilter(LogUtils.V)// log 文件过滤器，和 logcat 过滤器同理，默认 Verbose
                .setStackDeep(1)// log 栈深度，默认为 1
                .setStackOffset(0);// 设置栈偏移，比如二次封装的话就需要设置，默认为 0
        LogUtils.d(config.toString());
    }

    /**
     * 初始化数据库
     */
    private void initDatabase() {

        final Migration MIGRATION_1_2 = new Migration(1, 2) {
            @Override
            public void migrate(SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE IF NOT EXISTS `TokenContract` (`token_id` INTEGER NOT NULL, `name` TEXT, `redis_key` TEXT, `token_addr` TEXT, `dealer_addr` TEXT, `state` INTEGER NOT NULL, `market_token` TEXT, `icon_app` TEXT, `icon_web` TEXT, `buy_price` TEXT, `sell_price` TEXT, `without_fee_price` TEXT, `ambassador_begin` TEXT, `ambassador_end` TEXT, `offline_time` TEXT, PRIMARY KEY(`token_id`))");
            }
        };

        final Migration MIGRATION_2_3 = new Migration(2, 3) {
            @Override
            public void migrate(SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE IF NOT EXISTS `WalletTx` (`id` INTEGER NOT NULL, `symbol` TEXT, `cashflow` INTEGER NOT NULL, `nonce` TEXT, `from` TEXT, `to` TEXT, `gasLimit` TEXT, `gasPrice` TEXT, `data` TEXT, `gasUsed` TEXT, `txFee` TEXT, `value` TEXT, `balance` TEXT, `txTimeStamp` TEXT, `txHash` TEXT, `blockHeight` TEXT, `txReceiptStatus` INTEGER NOT NULL, PRIMARY KEY(`id`))");
            }
        };

        final Migration MIGRATION_3_4 = new Migration(3, 4) {
            @Override
            public void migrate(SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE IF NOT EXISTS `History` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `url` TEXT, `md5` TEXT, `icon` TEXT, `host` TEXT, `timestamp` INTEGER NOT NULL, `bookmark` INTEGER NOT NULL, `folder` TEXT, `desc` TEXT, `other1` TEXT, `other2` TEXT, `other3` TEXT, `other4` TEXT)");
            }
        };

        db = Room
                .databaseBuilder(this, AppDatabase.class, "dex4d_db")
                .addMigrations(MIGRATION_1_2, MIGRATION_2_3,MIGRATION_3_4)
                .build();
    }

    public static AppDatabase getDb() {
        return db;
    }

    /**
     * 此方法所在线程为工作线程
     *
     * @param s
     */
    @Override
    public void onStringAvailable(String s) {
        try {
            RPC rpc = new Gson().fromJson(s, RPC.class);
//            LogUtils.i("SERVER_PUSH", rpc);
            EventBus.getDefault().post(rpc);
        }catch (Exception e){
//            LogUtils.i("SERVER_PUSH_PARSE_ERROR", s);
//            LogUtils.e(e.getMessage());
        }

    }

    @Override
    public void onBecameForeground(Activity activity) {

        if (client != null) {
            client.resume();
        }

        if (activity instanceof TradeActivity) {//交易页面

        } else if (activity instanceof HomeActivity) {//主页

        } else if (activity instanceof AccountActivity) {//账户页面

        }
    }

    @Override
    public void onBecameBackground(Activity activity) {
        if (client != null) {
            client.pause();
        }
    }

    @Override
    public void onNormal(Activity activity) {

    }

}
